/**
 * 缓存组合式函数
 * 提供统一的缓存管理功能
 */

import { ref } from 'vue'

interface CacheOptions {
  expire?: number // 缓存过期时间（毫秒）
  key?: string // 自定义缓存键
}

interface CachedData<T> {
  data: T
  timestamp: number
  expire: number
}

/**
 * 创建缓存
 * @param fetcher 数据获取函数
 * @param options 缓存选项
 * @returns 缓存的数据和刷新函数
 */
export function useCachedData<T>(fetcher: () => Promise<T>, options: CacheOptions = {}) {
  const data = ref<T | null>(null)
  const loading = ref(false)
  const error = ref<Error | null>(null)
  const { expire = 5 * 60 * 1000, key } = options // 默认5分钟

  // 生成缓存键
  const cacheKey = key || `cache_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`

  /**
   * 从缓存获取数据
   */
  function getFromCache(): T | null {
    try {
      const cached = localStorage.getItem(cacheKey)
      if (cached) {
        const parsed: CachedData<T> = JSON.parse(cached)
        const now = Date.now()

        // 检查是否过期
        if (now - parsed.timestamp < parsed.expire) {
          return parsed.data
        } else {
          // 过期则删除缓存
          localStorage.removeItem(cacheKey)
        }
      }
    } catch (e) {
      console.error('Cache read error:', e)
    }
    return null
  }

  /**
   * 保存数据到缓存
   */
  function saveToCache(value: T) {
    try {
      const cacheData: CachedData<T> = {
        data: value,
        timestamp: Date.now(),
        expire,
      }
      localStorage.setItem(cacheKey, JSON.stringify(cacheData))
    } catch (e) {
      console.error('Cache write error:', e)
    }
  }

  /**
   * 清除缓存
   */
  function clearCache() {
    localStorage.removeItem(cacheKey)
  }

  /**
   * 刷新数据
   */
  async function refresh() {
    loading.value = true
    error.value = null

    try {
      const result = await fetcher()
      data.value = result
      saveToCache(result)
      return result
    } catch (e) {
      error.value = e as Error
      throw e
    } finally {
      loading.value = false
    }
  }

  /**
   * 初始化（先尝试缓存，后刷新）
   */
  async function init() {
    // 先尝试从缓存获取
    const cached = getFromCache()
    if (cached !== null) {
      data.value = cached
    }

    // 再异步刷新（不阻塞）
    refresh().catch(() => {
      // 静默失败，不影响用户体验
    })

    return data.value
  }

  return {
    data,
    loading,
    error,
    refresh,
    init,
    clearCache,
  }
}

/**
 * 内存缓存（页面级）
 */
const memoryCache = new Map<string, { data: any; timestamp: number; expire: number }>()

/**
 * 内存缓存 Hook
 */
export function useMemoryCache<T>(fetcher: () => Promise<T>, key: string, expire = 5 * 60 * 1000) {
  const data = ref<T | null>(null)
  const loading = ref(false)

  async function get() {
    // 检查内存缓存
    const cached = memoryCache.get(key)
    if (cached && Date.now() - cached.timestamp < cached.expire) {
      data.value = cached.data
      return cached.data
    }

    loading.value = true
    try {
      const result = await fetcher()
      data.value = result

      // 保存到内存缓存
      memoryCache.set(key, {
        data: result,
        timestamp: Date.now(),
        expire,
      })

      return result
    } finally {
      loading.value = false
    }
  }

  function clear() {
    memoryCache.delete(key)
    data.value = null
  }

  return {
    data,
    loading,
    get,
    clear,
  }
}

/**
 * 防抖缓存（用于搜索等高频操作）
 */
export function useDebouncedCache<T>(fetcher: (params: any) => Promise<T>, delay = 300) {
  let timer: number | null = null
  const data = ref<T | null>(null)
  const loading = ref(false)

  async function fetch(params: any) {
    return new Promise<T>((resolve, reject) => {
      // 清除之前的定时器
      if (timer) {
        clearTimeout(timer)
      }

      // 设置新的定时器
      timer = window.setTimeout(async () => {
        loading.value = true
        try {
          const result = await fetcher(params)
          data.value = result
          resolve(result)
        } catch (e) {
          reject(e)
        } finally {
          loading.value = false
        }
      }, delay)
    })
  }

  return {
    data,
    loading,
    fetch,
  }
}
